<!DOCTYPE html>
<html lang="en" data-color-mode="auto" data-light-theme="light" data-dark-theme="dark"  data-a11y-animated-images="system" data-a11y-link-underlines="true">
<head>

  <meta charset="utf-8">
  <meta http-equiv="Access-Control-Allow-Origin" content="*" />

  <link rel="assets" href="https://github.githubassets.com/">
  <link rel="dns-prefetch" href="https://github.githubassets.com">
  <link rel="preconnect" href="https://github.githubassets.com" crossorigin>

  <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/light-3e154969b9f9.css" />
  <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/dark-9c5b7a476542.css" />
  <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-primitives-4cf0d59ab51a.css" />
  <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-ff8ec1db4f06.css" />
  <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/global-dcca24a0602a.css" />
  <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/github-e4eed26e112b.css" />
  <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/repository-0f7cf89e325a.css" />
  <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/code-14def43eef8d.css" />

</head>
<!--
    /dromara/disjob/blob/  =>  https://github.com/dromara/disjob/blob/
    /dromara/disjob/raw/   =>  https://raw.githubusercontent.com/dromara/disjob/
    <meta http-equiv="Access-Control-Allow-Origin" content="*" />
-->

<body class="logged-out env-production page-responsive" style="word-wrap: break-word;">
<div class="clearfix container-xl px-md-4 px-lg-5 px-3">

















  <div class="Box-sc-g0xbh4-0 QkQOb js-snippet-clipboard-copy-unpositioned undefined" data-hpc="true">
    <article class="markdown-body entry-content container-lg" itemprop="text"><p align="center" dir="auto">
      <a target="_blank" rel="noopener noreferrer" href="https://github.com/dromara/disjob/blob/master/docs/images/logo.png"><img src="https://raw.githubusercontent.com/dromara/disjob/master/docs/images/logo.png" width="160" alt="Logo" style="max-width: 100%;"></a>
    </p>
      <p align="center" dir="auto">
        <strong>一款分布式的任务调度与分布式计算框架</strong>
      </p>
      <p align="center" dir="auto">
        <a href="https://www.apache.org/licenses/LICENSE-2.0.html" rel="nofollow"><img src="https://camo.githubusercontent.com/e63a2fe5e72b8bf4ac15e1190228cd6d84a70e9b05ac241d7bcb361e6e137998/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4170616368652d2d322e302d677265656e2e7376673f6c6f676f3d617061636865" alt="License" data-canonical-src="https://img.shields.io/badge/license-Apache--2.0-green.svg?logo=apache" style="max-width: 100%;"></a>
        <a href="https://www.oracle.com/java/technologies/downloads/#java8" rel="nofollow"><img src="https://camo.githubusercontent.com/37c81559b6cbfa1b87b8244c01409824073261436b3db5465755964d8af4e7b9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4a444b2d382b2d677265656e2e7376673f6c6f676f3d6f7261636c65266c6f676f436f6c6f723d6372696d736f6e" alt="JDK8+" data-canonical-src="https://img.shields.io/badge/JDK-8+-green.svg?logo=oracle&amp;logoColor=crimson" style="max-width: 100%;"></a>
        <a href="https://central.sonatype.com/namespace/cn.ponfee" rel="nofollow"><img src="https://camo.githubusercontent.com/53e934c8ca1172ce295ca0d7a0b73c659010cc6d4efa3eb94c9b2d77ecabeab0/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6d6176656e2d2d63656e7472616c2d322e312e392d6f72616e67652e7376673f7374796c653d706c6173746963266c6f676f3d6170616368656d6176656e" alt="Maven Central" data-canonical-src="https://img.shields.io/badge/maven--central-2.2.1-orange.svg?style=plastic&amp;logo=apachemaven" style="max-width: 100%;"></a>
        <a href="https://github.com/dromara/disjob/actions"><img src="https://github.com/dromara/disjob/workflows/build/badge.svg" alt="Build status" style="max-width: 100%;"></a>
        <a href="http://ponfee.cn:8000/" rel="nofollow"><img src="https://camo.githubusercontent.com/224150bf00f7288de92a6980c49c5463cace5cf4cbb33c793f7e00317286df12/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6f6e6c696e652d44656d6f2d626c75652e7376673f6c6f676f3d616972706c6179766964656f266c6f676f436f6c6f723d677265656e" alt="Demo" data-canonical-src="https://img.shields.io/badge/online-Demo-blue.svg?logo=airplayvideo&amp;logoColor=green" style="max-width: 100%;"></a>
      </p>
      <p align="center" dir="auto">
        在线演示：<a href="http://ponfee.cn:8000/" rel="nofollow">http://ponfee.cn:8000/</a>
      </p>
      <hr>
      <p dir="auto"><strong><code>简体中文</code></strong> | <a href="https://github.com/dromara/disjob/blob/master/README.en.md">English</a></p>
      <p dir="auto">一款分布式的任务调度与分布式计算框架，除了具备常规的任务调度功能外，还提供暂停/取消运行中的任务、恢复执行已暂停的任务、任务分片、失败重试、广播任务、任务依赖、工作流任务(DAG)、管理器与执行器分离部署、Web管理后台等能力。</p>
      <p dir="auto">轻量级，简单易用，特别适合长任务的执行。功能强大，稳定可靠，历经生产检验。</p>
      <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Architecture</h2><a id="user-content-architecture" class="anchor" aria-label="Permalink: Architecture" href="#architecture"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
      <ul dir="auto">
        <li>整体流程</li>
      </ul>
      <p dir="auto"><a target="_blank" rel="noopener noreferrer" href="https://github.com/dromara/disjob/blob/master/docs/images/architecture.jpg"><img src="https://raw.githubusercontent.com/dromara/disjob/master/docs/images/architecture.jpg" alt="Architecture" style="max-width: 100%;"></a></p>
      <ul dir="auto">
        <li>代码结构</li>
      </ul>
      <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="disjob                                        # 主项目①pom.xml
├── disjob-admin                              # 管理后台项目②pom.xml(基于Ruoyi框架二次开发)
├── disjob-alert                              # 告警模块
│   ├── disjob-alert-api                      # 告警的抽象接口层
│   ├── disjob-alert-email                    # 邮件告警
│   ├── disjob-alert-im                       # 即时通讯告警(钉钉、企业微信、飞书等)
│   └── disjob-alert-sms                      # 短信告警
├── disjob-bom                                # Maven项目bom模块
├── disjob-common                             # 公共的工具类模块
├── disjob-core                               # 任务调度相关的核心类（如枚举类、接口定义、接口参数等）
├── disjob-dispatch                           # 任务派发模块
│   ├── disjob-dispatch-api                   # 任务派发的抽象接口层
│   ├── disjob-dispatch-http                  # 任务派发的Http实现
│   └── disjob-dispatch-redis                 # 任务派发的Redis实现
├── disjob-id                                 # 分布式ID生成模块
├── disjob-registry                           # Server(Supervisor &amp; Worker)注册模块
│   ├── disjob-registry-api                   # Server注册中心的抽象接口层
│   ├── disjob-registry-consul                # Server注册中心：Consul实现
│   ├── disjob-registry-database              # Server注册中心：Database实现
│   ├── disjob-registry-etcd                  # Server注册中心：Etcd实现
│   ├── disjob-registry-nacos                 # Server注册中心：Nacos实现
│   ├── disjob-registry-redis                 # Server注册中心：Redis实现
│   └── disjob-registry-zookeeper             # Server注册中心：Zookeeper实现
├── disjob-reports                            # 聚合各个模块的测试覆盖率报告
├── disjob-samples                            # Samples项目③pom.xml
│   ├── disjob-samples-conf                   # Samples使用到的配置文件
│   ├── disjob-samples-frameless-worker       # Worker单独部署的范例（普通Java-main应用）
│   ├── disjob-samples-springboot-merged      # Supervisor与Worker合并部署的范例（Spring-boot应用）
│   ├── disjob-samples-springboot-supervisor  # Supervisor单独部署的范例（Spring-boot应用）
│   └── disjob-samples-springboot-worker      # Worker单独部署的范例（Spring-boot应用）
├── disjob-supervisor                         # Supervisor代码
├── disjob-test                               # 用于辅助测试
└── disjob-worker                             # Worker代码"><pre lang="text" class="notranslate"><code>disjob                                        # 主项目①pom.xml
├── disjob-admin                              # 管理后台项目②pom.xml(基于Ruoyi框架二次开发)
├── disjob-alert                              # 告警模块
│   ├── disjob-alert-api                      # 告警的抽象接口层
│   ├── disjob-alert-email                    # 邮件告警
│   ├── disjob-alert-im                       # 即时通讯告警(钉钉、企业微信、飞书等)
│   └── disjob-alert-sms                      # 短信告警
├── disjob-bom                                # Maven项目bom模块
├── disjob-common                             # 公共的工具类模块
├── disjob-core                               # 任务调度相关的核心类（如枚举类、接口定义、接口参数等）
├── disjob-dispatch                           # 任务派发模块
│   ├── disjob-dispatch-api                   # 任务派发的抽象接口层
│   ├── disjob-dispatch-http                  # 任务派发的Http实现
│   └── disjob-dispatch-redis                 # 任务派发的Redis实现
├── disjob-id                                 # 分布式ID生成模块
├── disjob-registry                           # Server(Supervisor &amp; Worker)注册模块
│   ├── disjob-registry-api                   # Server注册中心的抽象接口层
│   ├── disjob-registry-consul                # Server注册中心：Consul实现
│   ├── disjob-registry-database              # Server注册中心：Database实现
│   ├── disjob-registry-etcd                  # Server注册中心：Etcd实现
│   ├── disjob-registry-nacos                 # Server注册中心：Nacos实现
│   ├── disjob-registry-redis                 # Server注册中心：Redis实现
│   └── disjob-registry-zookeeper             # Server注册中心：Zookeeper实现
├── disjob-reports                            # 聚合各个模块的测试覆盖率报告
├── disjob-samples                            # Samples项目③pom.xml
│   ├── disjob-samples-conf                   # Samples使用到的配置文件
│   ├── disjob-samples-frameless-worker       # Worker单独部署的范例（普通Java-main应用）
│   ├── disjob-samples-springboot-merged      # Supervisor与Worker合并部署的范例（Spring-boot应用）
│   ├── disjob-samples-springboot-supervisor  # Supervisor单独部署的范例（Spring-boot应用）
│   └── disjob-samples-springboot-worker      # Worker单独部署的范例（Spring-boot应用）
├── disjob-supervisor                         # Supervisor代码
├── disjob-test                               # 用于辅助测试
└── disjob-worker                             # Worker代码
</code></pre></div>
      <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Features</h2><a id="user-content-features" class="anchor" aria-label="Permalink: Features" href="#features"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
      <ul dir="auto">
        <li>分为管理器(Supervisor)和执行器(Worker)两种角色，Supervisor与Worker可分离部署</li>
        <li>Supervisor与Worker通过注册中心相互发现，支持的注册中心有：Database、Redis、Consul、Nacos、Zookeeper、Etcd</li>
        <li>Supervisor负责生成任务，把任务派发给Worker执行，支持的任务派发方式有：Redis、Http</li>
        <li>需要指定Job的分组(group)，Job的任务只会派发给指定组的Worker执行</li>
        <li>提供任务分片的能力，重写拆分方法<a href="https://github.com/dromara/disjob/blob/master/disjob-worker/src/main/java/cn/ponfee/disjob/worker/executor/JobSplitter.java">JobSplitter#split</a>即可拆分为多个任务，实现分布式任务及并行执行</li>
        <li>支持暂停和取消运行中的任务，已暂停的任务可恢复继续执行，执行失败的任务支持重试</li>
        <li>支持任务保存(Savepoint)其执行状态，让手动或异常暂停的任务能从上一次的执行状态中恢复继续执行</li>
        <li>任务在执行时若抛出<a href="https://github.com/dromara/disjob/blob/master/disjob-worker/src/main/java/cn/ponfee/disjob/worker/exception/PauseTaskException.java">PauseTaskException</a>，会暂停对应实例下的全部任务(包括分派到其它worker机器的任务)</li>
        <li>支持广播任务，广播任务会派发给group下的所有worker执行</li>
        <li>支持Job间的父子依赖，多个Job配置好依赖关系后便会按既定的依赖顺序依次执行</li>
        <li>支持DAG工作流，可把<code>jobExecutor</code>配置为复杂的DAG表达式，如：A-&gt;B,C,(D-&gt;E)-&gt;F,G-&gt;H</li>
        <li>支持执行中的Task在Worker(服务)发布完成后自动恢复继续执行(见<code>shutdown_strategy</code>配置)</li>
        <li>提供Web管理后台，通过用户界面进行作业配置，任务监控等</li>
      </ul>
      <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Comparison</h2><a id="user-content-comparison" class="anchor" aria-label="Permalink: Comparison" href="#comparison"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
      <markdown-accessiblity-table><table>
        <thead>
        <tr>
          <th></th>
          <th><strong>Quartz</strong></th>
          <th><strong>Elastic-Job</strong></th>
          <th><strong>Xxl-Job</strong></th>
          <th><strong>Disjob</strong></th>
        </tr>
        </thead>
        <tbody>
        <tr>
          <td><strong>触发类型</strong></td>
          <td>Cron</td>
          <td>Cron</td>
          <td>Cron、固定频率、父子依赖</td>
          <td>Cron、指定时间、固定频率、固定延时、父子依赖</td>
        </tr>
        <tr>
          <td><strong>任务编排</strong></td>
          <td>无</td>
          <td>无</td>
          <td>无</td>
          <td>DAG表达式</td>
        </tr>
        <tr>
          <td><strong>任务分片</strong></td>
          <td>无</td>
          <td>静态分片</td>
          <td>广播任务</td>
          <td>广播任务、动态分片</td>
        </tr>
        <tr>
          <td><strong>停止与恢复</strong></td>
          <td>无</td>
          <td>无</td>
          <td>终止运行中的任务</td>
          <td>暂停执行中的任务、恢复执行已暂停的任务</td>
        </tr>
        <tr>
          <td><strong>保存执行快照</strong></td>
          <td>无</td>
          <td>无</td>
          <td>无</td>
          <td>有</td>
        </tr>
        <tr>
          <td><strong>失败重试</strong></td>
          <td>无</td>
          <td>失效转移</td>
          <td>有</td>
          <td>有</td>
        </tr>
        <tr>
          <td><strong>后台管理</strong></td>
          <td>无</td>
          <td>有</td>
          <td>有</td>
          <td>有</td>
        </tr>
        <tr>
          <td><strong>监控告警</strong></td>
          <td>无</td>
          <td>邮件</td>
          <td>邮件</td>
          <td>邮件、钉钉、企业微信、飞书、短信等</td>
        </tr>
        </tbody>
      </table></markdown-accessiblity-table>
      <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto"><a href="https://central.sonatype.com/namespace/cn.ponfee" rel="nofollow">Download From Maven Central</a></h2><a id="user-content-download-from-maven-central" class="anchor" aria-label="Permalink: Download From Maven Central" href="#download-from-maven-central"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
      <div class="highlight highlight-text-xml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;dependency&gt;
  &lt;groupId&gt;cn.ponfee&lt;/groupId&gt;
  &lt;artifactId&gt;disjob-{xxx}&lt;/artifactId&gt;
  &lt;version&gt;2.2.1&lt;/version&gt;
&lt;/dependency&gt;"><pre>&lt;<span class="pl-ent">dependency</span>&gt;
  &lt;<span class="pl-ent">groupId</span>&gt;cn.ponfee&lt;/<span class="pl-ent">groupId</span>&gt;
  &lt;<span class="pl-ent">artifactId</span>&gt;disjob-{xxx}&lt;/<span class="pl-ent">artifactId</span>&gt;
  &lt;<span class="pl-ent">version</span>&gt;2.2.1&lt;/<span class="pl-ent">version</span>&gt;
&lt;/<span class="pl-ent">dependency</span>&gt;</pre></div>
      <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Build From Source</h2><a id="user-content-build-from-source" class="anchor" aria-label="Permalink: Build From Source" href="#build-from-source"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
      <div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="./mvnw clean install -DskipTests -Dcheckstyle.skip=true -Dmaven.javadoc.skip=true -U"><pre>./mvnw clean install -DskipTests -Dcheckstyle.skip=true -Dmaven.javadoc.skip=true -U</pre></div>
      <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Quick Start</h2><a id="user-content-quick-start" class="anchor" aria-label="Permalink: Quick Start" href="#quick-start"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
      <ol dir="auto">
        <li>在开发工具中分别导入项目（分为三个独立的项目，共用一个<code>git</code>仓库）</li>
      </ol>
      <ul dir="auto">
        <li><a href="https://github.com/dromara/disjob/blob/master/pom.xml">主项目—disjob</a></li>
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-admin/pom.xml">管理后台—disjob-admin</a></li>
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-samples/pom.xml">范例项目—disjob-samples</a></li>
      </ul>
      <ol start="2" dir="auto">
        <li>启动以下各应用(执行java main方法)组成分布式调度集群</li>
      </ol>
      <blockquote>
        <p dir="auto">已配置不同的端口可同时启动，可以在开发工具中运行Java main方法，也可通过<code>java -jar</code>命令运行构建好的jar包</p>
      </blockquote>
      <ul dir="auto">
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-test/src/main/java/cn/ponfee/disjob/test/EmbeddedMysqlAndRedisServer.java">启动内嵌的本地Mysql &amp; Redis</a>
          <ul dir="auto">
            <li>MacOS系统若报<code>MariaDB</code>的“<a href="https://github.com/dromara/disjob/blob/master/disjob-test/DB/MariaDB/README.md">Library not loaded</a>”错误时参考</li>
            <li>使用客户端工具连接mysql时，用户名为<code>root</code>，无需密码</li>
            <li>启动时已经自动执行了初始化的SQL脚本</li>
            <li>启动失败需要检查下端口是否被占用（mysql端口3306，redis端口6379）</li>
          </ul>
        </li>
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-samples/disjob-samples-springboot-worker/src/main/java/cn/ponfee/disjob/samples/worker/WorkerApplication.java">启动Worker单独部署的Spring-boot应用</a></li>
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-samples/disjob-samples-frameless-worker/src/main/java/cn/ponfee/disjob/samples/worker/WorkerFramelessMain.java">启动Worker单独部署的普通Java-main应用</a></li>
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-samples/disjob-samples-springboot-merged/src/main/java/cn/ponfee/disjob/samples/merged/MergedApplication.java">启动Supervisor+Worker合并部署的Spring-boot应用</a></li>
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-samples/disjob-samples-springboot-supervisor/src/main/java/cn/ponfee/disjob/samples/supervisor/SupervisorApplication.java">启动Supervisor单独部署的Spring-boot应用</a></li>
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-admin/ruoyi-admin/src/main/java/com/ruoyi/DisjobAdminApplication.java">启动Admin管理后台的Spring-boot应用</a></li>
      </ul>
      <ol start="3" dir="auto">
        <li>登录管理后台</li>
      </ol>
      <ul dir="auto">
        <li>浏览器访问【 <a href="http://127.0.0.1:80/" rel="nofollow">http://127.0.0.1:80/</a> 】登录管理后台，用户名/密码：<code>admin</code>/<code>123456</code></li>
        <li>登录后在左侧菜单栏找到<code>调度管理</code>菜单，即可使用调度管理功能</li>
        <li><strong>Supervisor</strong>：查看Supervisor机器列表及其运行情况</li>
        <li><strong>管理分组</strong>：给管理员使用，用于管理所有的组数据(一个组可理解为是一个应用)</li>
        <li><strong>我的分组</strong>：给应用的开发人员使用，可查看每个组(应用)的Worker机器列表及其运行情况</li>
        <li><strong>作业配置</strong>：作业(job)配置，包括查看、新增、修改、删除、触发、禁用等</li>
        <li><strong>任务实例</strong>：job在某一时间点被触发执行的实例(instance)，一个实例会拆分成若干个任务(task)
          <ul dir="auto">
            <li>在页面上方的<code>第一个分页表格</code>是以树状(tree)方式展示任务实例，并支持下钻</li>
            <li>鼠标向下滚动页面后看到的<code>第二个分页表格</code>是以扁平(flat)方式展示任务实例</li>
          </ul>
        </li>
      </ul>
      <ol start="4" dir="auto">
        <li>链接地址</li>
      </ol>
      <ul dir="auto">
        <li>管理后台<strong>演示地址</strong>：【 <a href="http://ponfee.cn:8000/" rel="nofollow">http://ponfee.cn:8000/</a> 】，用户名/密码：<code>disjob</code>/<code>123456</code></li>
        <li>在线查看<strong>文档地址</strong>：<code>正在建设中，敬请期待！</code></li>
      </ul>
      <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">User Guide</h2><a id="user-content-user-guide" class="anchor" aria-label="Permalink: User Guide" href="#user-guide"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
      <ol dir="auto">
        <li>项目包含两个SQL脚本</li>
      </ol>
      <ul dir="auto">
        <li><a href="https://github.com/dromara/disjob/blob/master/sql/mysql-disjob.sql">核心框架的SQL脚本</a></li>
        <li><a href="https://github.com/dromara/disjob/blob/master/sql/mysql-disjob_admin.sql">管理后台的SQL脚本</a></li>
      </ul>
      <ol start="2" dir="auto">
        <li>在Maven pom文件中更改<code>注册中心disjob-registry-{xxx}</code>和<code>任务派发disjob-dispatch-{xxx}</code>的具体实现</li>
      </ol>
      <ul dir="auto">
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-samples/pom.xml">Samples项目</a></li>
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-admin/ruoyi-disjob/pom.xml">Admin项目</a></li>
        <li>默认使用<code>disjob-registry-redis</code>做注册中心，<code>disjob-dispatch-http</code>做任务派发</li>
      </ul>
      <ol start="3" dir="auto">
        <li>Samples项目配置文件【disjob-samples】</li>
      </ol>
      <ul dir="auto">
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-samples/disjob-samples-conf/application-mysql.yml">Supervisor角色Mysql配置</a></li>
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-samples/disjob-samples-conf/application-supervisor.yml">Supervisor角色核心配置</a></li>
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-samples/disjob-samples-conf/application-worker.yml">Worker角色核心配置</a>（Spring-boot应用）</li>
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-samples/disjob-samples-conf/application-redis.yml">Redis配置</a>（Worker与Supervisor共用，使用Redis做注册中心或任务派发时需要配置）</li>
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-samples/disjob-samples-conf/application-web.yml">Spring-boot Web相关配置</a>（Worker与Supervisor共用）</li>
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-samples/disjob-samples-frameless-worker/src/main/resources/worker-conf.yml">Worker角色普通Java-main应用配置</a></li>
      </ul>
      <ol start="4" dir="auto">
        <li>Admin项目配置文件【disjob-admin】</li>
      </ol>
      <ul dir="auto">
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-admin/ruoyi-disjob/src/main/resources/application-disjob-mysql.yml">Supervisor角色相关的Mysql配置</a></li>
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-admin/ruoyi-disjob/src/main/resources/application-disjob-redis.yml">Redis配置</a>（Worker与Supervisor共用，使用Redis做注册中心或任务派发时需要配置）</li>
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-admin/ruoyi-disjob/src/main/java/cn/ponfee/disjob/admin/DisjobAdminConfiguration.java">可加@EnableWorker注解启用Worker角色</a>（管理后台必须启用Supervisor角色）</li>
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-admin/ruoyi-admin/src/main/resources/application-druid.yml">管理后台功能相关的Mysql配置</a></li>
        <li><a href="http://doc.ruoyi.vip/ruoyi/document/hjbs.html#%E5%BF%85%E8%A6%81%E9%85%8D%E7%BD%AE" rel="nofollow">RuoYi框架相关配置参考官方文档</a>（只增加了<a href="https://github.com/dromara/disjob/blob/master/disjob-admin/ruoyi-disjob">ruoyi-disjob</a>模块，其它的RuoYi原有模块基本未改动）</li>
      </ul>
      <ol start="5" dir="auto">
        <li>各种注册中心配置类参考（Redis使用Spring-boot自带的配置方式）</li>
      </ol>
      <ul dir="auto">
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-registry/disjob-registry-consul/src/main/java/cn/ponfee/disjob/registry/consul/configuration/ConsulRegistryProperties.java">Consul</a></li>
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-registry/disjob-registry-database/src/main/java/cn/ponfee/disjob/registry/database/configuration/DatabaseRegistryProperties.java">Database</a></li>
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-registry/disjob-registry-zookeeper/src/main/java/cn/ponfee/disjob/registry/zookeeper/configuration/ZookeeperRegistryProperties.java">Zookeeper</a></li>
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-registry/disjob-registry-nacos/src/main/java/cn/ponfee/disjob/registry/nacos/configuration/NacosRegistryProperties.java">Nacos</a></li>
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-registry/disjob-registry-etcd/src/main/java/cn/ponfee/disjob/registry/etcd/configuration/EtcdRegistryProperties.java">Etcd</a></li>
      </ul>
      <blockquote>
        <p dir="auto">例如：若使用Consul做配置中心时，可加如下配置</p>
      </blockquote>
      <div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="disjob.registry.consul:
  namespace: disjob_registry
  host: localhost
  port: 8500
  token:"><pre><span class="pl-ent">disjob.registry.consul</span>:
  <span class="pl-ent">namespace</span>: <span class="pl-s">disjob_registry</span>
  <span class="pl-ent">host</span>: <span class="pl-s">localhost</span>
  <span class="pl-ent">port</span>: <span class="pl-c1">8500</span>
  <span class="pl-ent">token</span>:</pre></div>
      <ol start="6" dir="auto">
        <li>一些内嵌的本地Server</li>
      </ol>
      <ul dir="auto">
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-test/src/main/java/cn/ponfee/disjob/test/db/EmbeddedMysqlServerMariaDB.java">Mysql Server</a></li>
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-test/src/main/java/cn/ponfee/disjob/test/redis/EmbeddedRedisServerKstyrc.java">Redis Server</a></li>
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-registry/disjob-registry-zookeeper/src/test/java/cn/ponfee/disjob/registry/zookeeper/EmbeddedZookeeperServer.java">Zookeeper Server</a></li>
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-registry/disjob-registry-consul/src/test/java/cn/ponfee/disjob/registry/consul/EmbeddedConsulServerPszymczyk.java">Consul Server</a></li>
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-registry/disjob-registry-nacos/src/test/java/cn/ponfee/disjob/registry/nacos/EmbeddedNacosServerTestcontainers.java">Nacos Server</a>（依赖本地docker环境）</li>
        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-registry/disjob-registry-etcd/src/test/java/cn/ponfee/disjob/registry/etcd/EmbeddedEtcdServerTestcontainers.java">Etcd Server</a>（依赖本地docker环境）</li>
      </ul>
      <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Example</h2><a id="user-content-example" class="anchor" aria-label="Permalink: Example" href="#example"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
      <p dir="auto">举个简单的例子：统计在<code>(0，1万亿]</code>区间内质数的个数。如果是单机单线程CPU的话要统计很长时间，这里我们就可以使用本框架提供的分布式计算能力来解决此类问题。</p>
      <ol dir="auto">
        <li><strong>任务分片</strong></li>
      </ol>
      <p dir="auto">先根据当前的机器资源情况来决定拆分任务的数量，比如我们有5台机器及每台2 core CPU(质数统计是CPU密集型)，决定拆分为10个任务。</p>
      <ol start="2" dir="auto">
        <li><strong>派发任务</strong></li>
      </ol>
      <p dir="auto">Supervisor使用指定的路由算法把拆分的10个子任务派发给这些Worker机器。</p>
      <ol start="3" dir="auto">
        <li><strong>接收任务</strong></li>
      </ol>
      <p dir="auto">Worker接收到子任务后，会提交到框架自定义的线程池中执行。</p>
      <ol start="4" dir="auto">
        <li><strong>分布式并行计算</strong></li>
      </ol>
      <p dir="auto">在执行时我们可以使用分批次方式(通过代码循环)来统计，这里我们指定<code>task-1</code>在第一次循环统计<code>(0, 1亿]</code>，第二次循环统计<code>(10亿, 11亿]</code>，以此类推最后一次循环统计<code>(9990亿, 9991亿]</code>。同理其它的task也是按同样的方式分布式并行统计。</p>
      <blockquote>
        <p dir="auto">P.s. 黎曼猜想中可知质数分布是大体均匀的，判断一个数是否质数有很多方法，如埃氏筛法、欧拉筛法、Miller Rabin素性检验，这里我们可以使用Guava库提供的素性检验。</p>
      </blockquote>
      <ol start="5" dir="auto">
        <li><strong>Savepoint</strong></li>
      </ol>
      <p dir="auto">如果在统计过程中机器宕机后怎么办？难道再从头开始统计吗？No No No！我们可以在每循环10次(或每隔执行超过1分钟)时使用<code>Savepoint</code>保存当前<code>task-1</code>的执行快照。宕机异常后的重新启动任务时会读取这份快照数据，从上一次的状态中接着继续统计。以下是<code>task-1</code>任务保存的快照数据样例</p>
      <div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{
  &quot;next&quot;: 4000000001, // 下一次循环时要统计的区间为(40亿, 41亿]
  &quot;count&quot;: 19819734,  // 已经统计到了 19819734 个质数
  &quot;finished&quot;: false   // 当前任务是否已经统计完成：true-是；false-否；
}"><pre><span class="pl-kos">{</span>
  <span class="pl-s">"next"</span>: <span class="pl-c1">4000000001</span><span class="pl-kos">,</span> <span class="pl-c">// 下一次循环时要统计的区间为(40亿, 41亿]</span>
  <span class="pl-s">"count"</span>: <span class="pl-c1">19819734</span><span class="pl-kos">,</span>  <span class="pl-c">// 已经统计到了 19819734 个质数</span>
  <span class="pl-s">"finished"</span>: <span class="pl-c1">false</span>   <span class="pl-c">// 当前任务是否已经统计完成：true-是；false-否；</span>
<span class="pl-kos">}</span></pre></div>
      <ol start="6" dir="auto">
        <li><strong>服务发布</strong></li>
      </ol>
      <p dir="auto">这些Task正在执行中，假如此时需要重新发布Worker(服务)该怎么办？Don't worry！在Worker发布的过程中无需人工干预，等服务发布完成一段时间后Task会自动恢复继续执行。</p>
      <ol start="7" dir="auto">
        <li><strong>暂停与恢复</strong></li>
      </ol>
      <p dir="auto">假如我们的这几台机器资源需要临时做其它的事情，想把当前的统计任务暂停一段时间。No problem！框架是支持<code>暂停执行中的任务</code>，只需要在管理后台的<code>任务实例</code>页面，找到该任务点击<code>暂停</code>按钮即可。在暂停时任务会接收到一个中断信号，收到中断信号时同样可以在代码中使用<code>Savepoint</code>保存当前的执行快照。</p>
      <p dir="auto">当其它事情执行完后，我们可以在管理后台的<code>任务实例</code>页面，找到被暂停的这个任务，点击<code>恢复</code>按钮，此时任务会从上一次保存的状态中恢复继续执行。</p>
      <ol start="8" dir="auto">
        <li><strong>异常中断</strong></li>
      </ol>
      <p dir="auto">子任务在执行过程中若抛出框架的<a href="https://github.com/dromara/disjob/blob/master/disjob-worker/src/main/java/cn/ponfee/disjob/worker/exception/PauseTaskException.java">PauseTaskException</a>，则会<code>暂停</code>对应任务实例下全部的10个子任务(包括派发在不同机器中的任务)。同样如果抛出<a href="https://github.com/dromara/disjob/blob/master/disjob-worker/src/main/java/cn/ponfee/disjob/worker/exception/CancelTaskException.java">CancelTaskException</a>则会<code>取消</code>对应任务实例下全部的10个子任务。如果抛出其它类型的异常时，只会<code>取消</code>当前子任务，对应任务实例下其它的子任务不受影响。</p>
      <ol start="9" dir="auto">
        <li><strong>任务编排</strong></li>
      </ol>
      <p dir="auto">现在这个质数统计的总任务已经执行完了，共10个子任务，每个子任务都统计出了它的那部分结果。Disjob能自动帮我汇总结果吗？Yes！框架提供了非常强大且方便的表达式来编排任务，如：<code>A-&gt;B,C,(D-&gt;E)-&gt;F,G-&gt;H</code>，现在我们就可以创建一个汇总任务，然后再把这两个任务编排在一起。</p>
      <p dir="auto">以下是本例质数统计中的job数据，只列了一些主要字段，其中<code>jobExecutor</code>编排了这两个任务执行器(见项目源码)</p>
      <div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{
  &quot;group&quot;: &quot;app-test&quot;,
  &quot;jobName&quot;: &quot;prime-count-dag&quot;,
  &quot;jobState&quot;: 1, // job状态：0-禁用；1-启用；
  &quot;jobType&quot;: 2,  // job类型：1-常规；2-工作流(DAG)；
  &quot;jobExecutor&quot;: &quot;cn.ponfee.disjob.test.executor.PrimeCountJobExecutor -&gt; cn.ponfee.disjob.test.executor.PrimeAccumulateJobExecutor&quot;,
  &quot;jobParam&quot;: &quot;{\&quot;m\&quot;:1,\&quot;n\&quot;:10000000000,\&quot;blockSize\&quot;:100000000,\&quot;parallel\&quot;:10}&quot;,
  &quot;triggerType&quot;: 2,
  &quot;triggerValue&quot;: &quot;2023-09-02 18:00:00&quot;
}"><pre><span class="pl-kos">{</span>
  <span class="pl-s">"group"</span>: <span class="pl-s">"app-test"</span><span class="pl-kos">,</span>
  <span class="pl-s">"jobName"</span>: <span class="pl-s">"prime-count-dag"</span><span class="pl-kos">,</span>
  <span class="pl-s">"jobState"</span>: <span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c">// job状态：0-禁用；1-启用；</span>
  <span class="pl-s">"jobType"</span>: <span class="pl-c1">2</span><span class="pl-kos">,</span>  <span class="pl-c">// job类型：1-常规；2-工作流(DAG)；</span>
  <span class="pl-s">"jobExecutor"</span>: <span class="pl-s">"cn.ponfee.disjob.test.executor.PrimeCountJobExecutor -&gt; cn.ponfee.disjob.test.executor.PrimeAccumulateJobExecutor"</span><span class="pl-kos">,</span>
  <span class="pl-s">"jobParam"</span>: <span class="pl-s">"{\"m\":1,\"n\":10000000000,\"blockSize\":100000000,\"parallel\":10}"</span><span class="pl-kos">,</span>
  <span class="pl-s">"triggerType"</span>: <span class="pl-c1">2</span><span class="pl-kos">,</span>
  <span class="pl-s">"triggerValue"</span>: <span class="pl-s">"2023-09-02 18:00:00"</span>
<span class="pl-kos">}</span></pre></div>
      <blockquote>
        <p dir="auto">本例中的质数统计流程图如下</p>
      </blockquote>
      <p dir="auto"><a target="_blank" rel="noopener noreferrer" href="https://github.com/dromara/disjob/blob/master/docs/images/example-flow.png"><img src="https://raw.githubusercontent.com/dromara/disjob/master/docs/images/example-flow.png" alt="范例流程图" style="max-width: 100%;"></a></p>
      <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Contributing</h2><a id="user-content-contributing" class="anchor" aria-label="Permalink: Contributing" href="#contributing"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
      <p dir="auto">如有发现bug、更优的实现方案、新特性等，可提交PR或新建<a href="/dromara/disjob/issues">Issues</a>。</p>
      <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Communication</h2><a id="user-content-communication" class="anchor" aria-label="Permalink: Communication" href="#communication"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
      <p dir="auto">扫码添加微信好友，备注<code>disjob</code>，邀您加入群聊</p>
      <p dir="auto"><a target="_blank" rel="noopener noreferrer" href="https://github.com/dromara/disjob/blob/master/docs/images/wechat.jpg"><img src="https://raw.githubusercontent.com/dromara/disjob/master/docs/images/wechat.jpg" width="230" alt="Wechat group" style="max-width: 100%;"></a></p>
      <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">TODO List</h2><a id="user-content-todo-list" class="anchor" aria-label="Permalink: TODO List" href="#todo-list"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
      <ul class="contains-task-list">
        <li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> 扩展注册中心：Zookeeper、Etcd、Nacos</li>
        <li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> 工作流任务(Workflow DAG)</li>
        <li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> 管理后台：用户体系、权限控制、调度管理等</li>
        <li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> 任务执行告警：邮件、短信、电话、飞书、钉钉、微信</li>
        <li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> 搭建一个关于项目使用说明的文档站点</li>
        <li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> 任务执行情况的可视化监控BI(Dashboard)</li>
      </ul>
    </article>
  </div>
















</div>
</body>
</html>
